#pragma once
#include "input.h"
#include "renderer.h"

#include <stdexcept>
#include <string>

namespace krryn{
namespace core{
	class job_manager;
}
namespace system{
	class driver;

	struct invalid_input_exception : std::runtime_error{
		invalid_input_exception(const std::string &a_What) : runtime_error(a_What) {}
	};

	struct subsystem_not_found : std::runtime_error{
		subsystem_not_found(const std::string &a_What) : runtime_error(a_What) {}
	};

	struct driver_factory{
		virtual driver *create() = 0;
	};

	class viewport_settings{
	public:
		int m_Width;
		int m_Height;
		int m_BitsPerPixel;

		viewport_settings() : m_Width(640), m_Height(480), m_BitsPerPixel(32) {}
	};

	class window_settings{
	public:
		viewport_settings m_Viewport;
		std::string m_Title;
		bool m_Fullscreen;

		window_settings() : m_Viewport(), m_Fullscreen(false), m_Title("krryn") {}
	};

	class driver{
	public:
		virtual ~driver() {}
		
		virtual renderer *create_renderer(core::job_manager *a_Manager, const window_settings &a_Settings = window_settings()) = 0;

		// get a handle to the default driver
		static driver *create();

		// get a handle to a named driver
		static driver *create(const std::string &a_Name);

		// attach a driver
		static void attach(const std::string &a_Name, driver_factory *a_Registration);
	};
}
}
